package com.iflytek.cosmo.ocr.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import com.iflytek.cosmo.ocr.common.constant.CommonConstant;
import com.iflytek.cosmo.ocr.common.enums.LicenseEnum;
import com.iflytek.cosmo.ocr.common.util.UUIDUtil;
import com.iflytek.cosmo.ocr.dao.AuthorizationLicenseDao;
import com.iflytek.cosmo.ocr.dao.AuthorizationMacDao;
import com.iflytek.cosmo.ocr.dao.IflyBarAuthDao;
import com.iflytek.cosmo.ocr.dao.MacLicenseDao;
import com.iflytek.cosmo.ocr.model.domain.MessageOutput;
import com.iflytek.cosmo.ocr.model.domain.State;
import com.iflytek.cosmo.ocr.model.entity.LicenseEntity;
import com.iflytek.cosmo.ocr.model.entity.MacLicenseEntity;
import com.iflytek.cosmo.ocr.service.AuthorizationService;
import com.iflytek.cosmo.ocr.web.vo.AuthrizationVO;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import static com.iflytek.cosmo.ocr.common.enums.LicenseEnum.FORMAL;
import static com.iflytek.cosmo.ocr.common.enums.LicenseEnum.FREE;
import static com.iflytek.cosmo.ocr.common.enums.LicenseEnum.TRIAL;

/**
 * @author ViviZhou
 * @create 2019-12-12 17:17
 */
@Service
public class AuthorizationServiceImpl implements AuthorizationService {

    private Logger logger = LoggerFactory.getLogger(AuthorizationServiceImpl.class);

    @Autowired
    AuthorizationMacDao authorizationMacDao;

    @Autowired
    IflyBarAuthDao iflyBarAuthDao;

    @Autowired
    AuthorizationLicenseDao authorizationLicenseDao;

    @Autowired
    MacLicenseDao macLicenseDao;
    //试用过期时间，单位天
    @Value("${license.validateDateMap.trial:0}")
    public int trialTimeDay;

    @Value("${license.validateDateMap.formal:0}")
    public int formalTimeMonth;

    @Value("${license.validateDateMap.free:0}")
    public int freeTimeYear;


    @Override
    public List<MacLicenseEntity> findLicenseId(List<String> macOrMainBoardAdd) {
        Example example = new Example(MacLicenseEntity.class);
        example.createCriteria().andIn("mac", macOrMainBoardAdd);
        List<MacLicenseEntity> macLicenseEntities = authorizationMacDao.selectByExample(example);
        return macLicenseEntities;
    }

    @Override
    public List<LicenseEntity> findLicense(List<String> codeIdList) {
        Example example = new Example(LicenseEntity.class);
        example.createCriteria().andIn("id", codeIdList);
        List<LicenseEntity> licenseEntities = authorizationLicenseDao.selectByExample(example);
        return licenseEntities;
    }

    @Override
    public String generateAuthorizationCode(String type) {
        //生成一条授权码，并插入数据库
        LicenseEntity licenseEntity = new LicenseEntity();
        //授权码的id值
        String licenseId = UUIDUtil.getUUID();
        licenseEntity.setId(licenseId);
        licenseEntity.setCode(UUID.randomUUID().toString().toUpperCase());
        Date currentTime = new Date();
        licenseEntity.setCreateTime(currentTime);
        licenseEntity.setActiveTime(currentTime);
        LicenseEnum enumType = LicenseEnum.getByCode(type);
        switch(enumType){
            case FREE:
                setAttributeByEnumType(licenseEntity, enumType, freeTimeYear, currentTime);
                break;
            case FORMAL:
                setAttributeByEnumType(licenseEntity, enumType, formalTimeMonth, currentTime);
                break;
            case TRIAL:
                setAttributeByEnumType(licenseEntity, enumType, trialTimeDay, currentTime);
                break;
            default:
                break;
        }
        //将生成的授权码插入license数据库
        authorizationLicenseDao.insertSelective(licenseEntity);
        return licenseId;
    }

    @Override
    public void bindLicenseAndMac(String licenseId, List<String> motherBoardList) {
        //将授权码与物理地址绑定
        List<MacLicenseEntity> macLicenseEntities = new ArrayList<>();
        Date currentTime = new Date();
        for (String macAddress : motherBoardList){
            MacLicenseEntity macLicenseEntity = new MacLicenseEntity();
            macLicenseEntity.setId(UUIDUtil.getUUID());
            macLicenseEntity.setMac(macAddress);
            macLicenseEntity.setCodeId(licenseId);
            macLicenseEntity.setCreateTime(currentTime);
            macLicenseEntities.add(macLicenseEntity);
        }
        //批量插入授权码与物理地址的绑定信息,此处调用的是maclicensedao
        macLicenseDao.insertBatch(macLicenseEntities);
    }

    public void setAttributeByEnumType(LicenseEntity licenseEntity, LicenseEnum enumType, int expireTime, Date currentTime){
        String type = enumType.getCode();
        licenseEntity.setType(type);
        Date expireDate = getExpireTime(currentTime, expireTime, type);
        licenseEntity.setExpireTime(expireDate);
        licenseEntity.setState(LicenseEnum.USED.getCode());
    }

    public Date getExpireTime(Date currentTime, int expireTime, String type){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentTime);
        LicenseEnum licenseEnum = LicenseEnum.getByCode(type);
        switch(licenseEnum){
            case FREE:
                calendar.add(Calendar.YEAR, expireTime);
                break;
            case FORMAL:
                calendar.add(Calendar.MONTH, expireTime);
                break;
            case TRIAL:
                calendar.add(Calendar.DATE, expireTime);
                break;
            default:
                break;
        }
        Date expireDate = calendar.getTime();
        return expireDate;
    }

    @Override
    public String getCodeId(String mac) {
        Example example = new Example(MacLicenseEntity.class);
        example.createCriteria().andEqualTo("mac", mac);
        List<MacLicenseEntity> macLicenseEntities = authorizationMacDao.selectByExample(example);
        return macLicenseEntities.get(0).getCodeId();
    }

    public static void main(String[] args) {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,15);
        Date date1 = calendar.getTime();
        System.out.println(date1);
    }

    @Override
    public LicenseEntity findLicenseEntityById(String id) {
        LicenseEntity licenseEntity = authorizationLicenseDao.selectByPrimaryKey(id);
        return licenseEntity;
    }

    @Override
    public MessageOutput freeAuthorizationModel(String[] macIdArray, AuthrizationVO authrizationVO, List<String> motherBoardList, LicenseEntity licenseEntity) {
        logger.info("进入免授权模式");
        List<String> authMacList = iflyBarAuthDao.verifyAuth(macIdArray);
        authrizationVO.setType(FREE.getCode());
        if (CollectionUtils.isEmpty(authMacList)){
            // 1.没有查到授权物理地址集合，则创建授权码
            String licenseId = generateAuthorizationCode(FREE.getCode());
            // 2.将授权码与物理地址绑定
            bindLicenseAndMac(licenseId, motherBoardList);
            authrizationVO.setExpire(false);
            return new MessageOutput(new State(CommonConstant.SUCCESS_CODE,"免授权成功"), authrizationVO);
        }else {
            // 部分授权mac
            Date currentTime = new Date();
            if (licenseEntity != null){
                Date expireTime = licenseEntity.getExpireTime();
                int compareResult = currentTime.compareTo(expireTime);
                if (compareResult <= 0){
                    authrizationVO.setExpire(false);
                }else {
                    authrizationVO.setExpire(true);
                }
                // 查询到部分,未授权
                List<String> unmacLicenseList = motherBoardList.stream().filter(t -> !authMacList.contains(t)).collect(Collectors.toList());
                // 集合不为空，绑定授权码
                if (CollectionUtils.isNotEmpty(unmacLicenseList)){
                    List<MacLicenseEntity> macLicenseEntities = new ArrayList<>();
                    // 根据其中的一个mac 查询原来的licenseid
                    String codeId = licenseEntity.getId();
                    for (String unmacLicense : unmacLicenseList){
                        MacLicenseEntity macLicenseEntity = new MacLicenseEntity();
                        macLicenseEntity.setId(UUIDUtil.getUUID());
                        macLicenseEntity.setMac(unmacLicense);
                        macLicenseEntity.setCodeId(codeId);
                        macLicenseEntity.setCreateTime(currentTime);
                        macLicenseEntities.add(macLicenseEntity);
                    }
                    // 批量插入
                    macLicenseDao.insertBatch(macLicenseEntities);
                }
                return new MessageOutput(new State(CommonConstant.SUCCESS_CODE, "免授权成功"), authrizationVO);
            }
        }
        return null;
    }

    @Override
    public MessageOutput noneFreeAuthorizationModel(LicenseEntity licenseEntity, AuthrizationVO authrizationVO) {
        if (licenseEntity == null){
            // licenseEntity为空，表示该用户未授权过，
            return new MessageOutput(new State(CommonConstant.FAIL_CODE, "用户从未授权"), authrizationVO);
        }else {
            // licenseEntity不为空，则判断是否过期
            LicenseEnum licenseEnum = LicenseEnum.getByCode(licenseEntity.getType());
            Date currentTime = new Date();
            switch (licenseEnum) {
                case FREE:
                    authrizationVO.setType(FREE.getCode());
                    break;
                case FORMAL:
                    authrizationVO.setType(FORMAL.getCode());
                    break;
                case TRIAL:
                    authrizationVO.setType(TRIAL.getCode());
                    break;
                default:
                    break;
            }
            // 比较是否过期
            compareExpireTime(authrizationVO, currentTime, licenseEntity);
            return new MessageOutput(new State(CommonConstant.FAIL_CODE), authrizationVO);
        }
    }

    public void compareExpireTime(AuthrizationVO authrizationVO, Date currentTime, LicenseEntity licenseEntity){
        Date expireTime = licenseEntity.getExpireTime();
        int compareResult = currentTime.compareTo(expireTime);
        if (compareResult >= 0){
            authrizationVO.setExpire(true);
        }else {
            authrizationVO.setExpire(false);
        }

    }


}
